﻿using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Owin;

namespace Flickr.Owin.Security.FlickrOAuth
{
    internal static class FlickrOAuthHandler
    {
        public const string RequestTokenUrl = "http://www.flickr.com/services/oauth/request_token";

        public const string AccessTokenUrl = "http://www.flickr.com/services/oauth/access_token";

        private static Dictionary<string, string> OAuthGetBasicParameters(string apiKey)
        {
            return new Dictionary<string, string>()
              {
                {
                  "oauth_nonce",
                  Guid.NewGuid().ToString("N")
                },
                {
                  "oauth_timestamp",
                  UtilityMethods.DateToUnixTimestamp(DateTime.UtcNow)
                },
                {
                  "oauth_version",
                  "1.0"
                },
                {
                  "oauth_signature_method",
                  "HMAC-SHA1"
                },
                {
                  "oauth_consumer_key",
                  apiKey
                }
              };
        }

        public static async Task<OAuthAccessToken> GetAccessToken(string requestToken, string requestTokenSecret, string verifier, string apiKey,string apiSecret, HttpClient httpClient, IOwinRequest request)
        {
            Dictionary<string, string> parameters = OAuthGetBasicParameters(apiKey);
            parameters.Add("oauth_verifier", verifier);
            parameters.Add("oauth_token", requestToken);
            string signature = UtilityMethods.OAuthCalculateSignature("POST", AccessTokenUrl, parameters, requestTokenSecret, apiSecret);
            parameters.Add("oauth_signature", signature);

            var requestBody = new FormUrlEncodedContent(parameters);

            HttpResponseMessage response = await httpClient.PostAsync(AccessTokenUrl, requestBody, request.CallCancelled);
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();
            
            OAuthAccessToken oauthAccessToken = OAuthAccessToken.ParseResponse(responseBody);

            return oauthAccessToken;
        }

        public static async Task<OAuthRequestToken> GetRequestToken(string callback, string apiKey, string apiSecret, HttpClient httpClient, IOwinRequest request)
        {
            Dictionary<string, string> parameters = OAuthGetBasicParameters(apiKey);
            parameters.Add("oauth_callback", callback);
            string str2 = UtilityMethods.OAuthCalculateSignature("POST", RequestTokenUrl, parameters, (string)null, apiSecret);
            parameters.Add("oauth_signature", str2);

            var requestBody = new FormUrlEncodedContent(parameters);

            HttpResponseMessage response = await httpClient.PostAsync(RequestTokenUrl, requestBody, request.CallCancelled);
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();

            return OAuthRequestToken.ParseResponse(responseBody);
        }

        public static string OAuthCalculateAuthorizationUrl(string requestToken, AuthLevel perms)
        {
            return OAuthCalculateAuthorizationUrl(requestToken, perms, false);
        }

        public static string OAuthCalculateAuthorizationUrl(string requestToken, AuthLevel perms, bool mobile)
        {
            string str = perms == AuthLevel.None ? "" : "&perms=" + UtilityMethods.AuthLevelToString(perms);
            return "http://" + (mobile ? "m" : "www") + ".flickr.com/services/oauth/authorize?oauth_token=" + requestToken + str;
        }
    }

}
